function PadlockModel(grid) {
	if (grid == null) {
		this.grid = this.createInitialGrid();
	} else {
		this.grid = grid;
	}
}

PadlockModel.prototype.createInitialGrid = function() {
	var grid = [];

	grid[0] = 1;
	grid[1] = 1;
	grid[2] = 1;

	grid[3] = 0;

	grid[4] = -1;
	grid[5] = -1;
	grid[6] = -1;

	return grid;
};

PadlockModel.prototype.checkBounds = function(pos) {
	if (!this.inBounds(pos)) {
		throw pos + " is not a valid move coordinate";
	}

};

PadlockModel.prototype.inBounds = function(pos) {
	return inBounds(0, this.grid.length, pos);
};

PadlockModel.prototype.getNextPosition = function(pos) {
	this.checkBounds(pos);

	var currentPlayer = this.grid[pos];
	if (currentPlayer == 0) {
		return {
			canMove : false,
			player : currentPlayer
		};
	}

	var direction = currentPlayer;
	var nextPos = pos + direction;
	var overtakePos = pos + 2 * direction;

	var canMove = this.inBounds(nextPos) && this.grid[nextPos] == 0;
	var canOvertakeOpponent = this.inBounds(overtakePos) && this.grid[nextPos] != currentPlayer
			&& this.grid[overtakePos] == 0;

	return {
		canMove : canMove || canOvertakeOpponent,
		position : (canMove) ? nextPos : overtakePos,
		player : currentPlayer
	};
};

PadlockModel.prototype.move = function(pos) {
	var nextPosition = this.getNextPosition(pos);

	if (nextPosition.canMove) {
		this.grid[pos] = 0;
		this.grid[nextPosition.position] = nextPosition.player;
	}
};

PadlockModel.prototype.hasWon = function() {
	var winCondition = [ -1, -1, -1, 0, 1, 1, 1 ];
	for ( var i = 0; i < winCondition.length; i++) {
		if (winCondition[i] != this.grid[i]) {
			return false;
		}
	}

	return true;
};

PadlockModel.prototype.getGrid = function() {
	return this.grid;
};

function inBounds(lowerBound, upperBound, index) {
	return (lowerBound <= index) && (upperBound > index);
}

// *********************** Controller ***********************
function PadlockController(view, initialConfig) {
	if (view == null) {
		view = emptyView();
	}
	this.view = view;
	this.model = new PadlockModel(initialConfig);

	this.view.init(this);

	function emptyView() {
		return {
			refresh : function() {
			},
			onSolved : function() {
			},
			init : function() {
			},
			reset : function() {

			}
		};
	}
}

PadlockController.prototype.show = function() {
	this.view.refresh(this.model.getGrid());
};

PadlockController.prototype.onMove = function(pos) {
	this.model.move(pos);
	this.view.refresh(this.model.getGrid());

	if (this.model.hasWon()) {
		new AEnigmatesStorage("padlock").solved();
		this.view.onSolved();
	}
};

PadlockController.prototype.onReset = function() {
	this.model = new PadlockModel();
	this.view.reset();
	this.view.refresh(this.model.getGrid());
};